package com.cpi.cornpp.purchase.program.services;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.collections.CollectionUtils;

import com.cpi.cornpp.common.exception.CornPPException;
import com.cpi.cornpp.purchase.program.converter.PurchaseOrderChargeConverter;
import com.cpi.cornpp.purchase.program.converter.PurchaseOrderConverter;
import com.cpi.cornpp.purchase.program.converter.PurchaseProgramConverter;
import com.cpi.cornpp.purchase.program.dao.PurchaseOrderChargeDAO;
import com.cpi.cornpp.purchase.program.dao.PurchaseOrderDAO;
import com.cpi.cornpp.purchase.program.dao.PurchaseProgramDAO;
import com.cpi.cornpp.purchase.program.dto.PurchaseOrderChargeDTO;
import com.cpi.cornpp.purchase.program.dto.PurchaseOrderDTO;
import com.cpi.cornpp.purchase.program.dto.PurchaseProgramDTO;
import com.cpi.cornpp.purchase.program.exception.PurchaseProgramException;
import com.cpi.cornpp.purchase.program.view.PurchaseOrderAssignFutureView;
import com.cpi.cornpp.purchase.program.view.PurchaseOrderAssignFuturesView;
import com.cpi.cornpp.purchase.program.view.PurchaseOrderChargeView;
import com.cpi.cornpp.purchase.program.view.PurchaseOrderView;
import com.cpi.cornpp.purchase.program.view.PurchaseProgramView;
import com.cpi.cornpp.purchaseorder.dto.PurchaseOrderAssignFutureDTO;
import com.cpi.cornpp.purchaseorder.spot.converter.PurchaseOrderSpotConverter;
import com.cpi.cornpp.purchaseorder.spot.dao.PurchaseOrderSpotDAO;
import com.cpi.cornpp.purchaseorder.spot.dto.PurchaseOrderSpotDTO;
import com.cpi.cornpp.purchaseorder.spot.view.PurchaseOrderSpotView;

/**
 * Purchase Program Service
 * @author Edgar Joao
 *
 */
public class PurchaseProgramService {
	
	private static final String INSERT_PURCHASE_ORDER_ERROR_MESSAGE_KEY = "error.message.purchaseprogram.purchaseorder.insert";
	
	/**
	 * @author Edgar Joao
	 * @param orderField
	 * @param ascendingOrder
	 * @return
	 * @throws PurchaseProgramException
	 */
	public List list(int orderField, boolean ascendingOrder, int biWeekInit, int biWeekEnd, int transportId) throws PurchaseProgramException {	
		PurchaseProgramDAO purchaseProgramDAO = null;
		PurchaseProgramConverter purchaseProgramConverter = null;
		List purchaseProgramListDTOs = null;
		List purchaseProgramListViews = null;
		
		try{			
			purchaseProgramDAO = new PurchaseProgramDAO();
			purchaseProgramConverter = new PurchaseProgramConverter();
			purchaseProgramListDTOs = new ArrayList(0);
			purchaseProgramListViews = new ArrayList(0);
			
			purchaseProgramListDTOs = purchaseProgramDAO.list(orderField, ascendingOrder, biWeekInit, biWeekEnd, transportId);
			purchaseProgramListViews = purchaseProgramConverter.converterDTOs(purchaseProgramListDTOs);
			
		} catch (PurchaseProgramException purchaseProgramException) {
			purchaseProgramException.printStackTrace(System.out);
			purchaseProgramException= new PurchaseProgramException(purchaseProgramException, CornPPException.LAYER_SERVICE,CornPPException.ACTION_LISTS);
			throw purchaseProgramException;
		}catch (Exception e){
			PurchaseProgramException purchaseProgramException = null;
			e.printStackTrace(System.out);
			purchaseProgramException = new PurchaseProgramException(e , CornPPException.LAYER_SERVICE,CornPPException.ACTION_LISTS);
			throw purchaseProgramException;
		}			
		return purchaseProgramListViews;
	}
	
	/**
	 * @author Edgar Joao
	 * @param purchaseProgramView
	 * @throws PurchaseProgramException
	 */
	public void deletePurchaseProgram(PurchaseProgramView purchaseProgramView) throws PurchaseProgramException {
		PurchaseProgramDAO purchaseProgramDAO = null;
		PurchaseProgramDTO purchaseProgramDTO = null;
		PurchaseProgramConverter purchaseProgramConverter = null;
		
		if(purchaseProgramView != null){
			purchaseProgramDAO = new PurchaseProgramDAO();
			purchaseProgramConverter = new PurchaseProgramConverter();
			
			purchaseProgramDTO = purchaseProgramConverter.converterPurchaseProgramViewToDTO(purchaseProgramView);
			
			try {
				purchaseProgramDAO.deletePurchaseProgram(purchaseProgramDTO);
			} catch (PurchaseProgramException purchaseProgramException) {
				throw purchaseProgramException;
			}catch(Exception e){
				PurchaseProgramException purchaseProgramException = new PurchaseProgramException(e, 
															PurchaseProgramException.LAYER_SERVICE, 
															PurchaseProgramException.ACTION_DELETE);
				e.printStackTrace(System.out);
				throw purchaseProgramException;				
			}			
		}
	}
	
	public void addPurchaseOrder(PurchaseOrderView purchaseOrderView, boolean generatorUsed) throws PurchaseProgramException{
		int purchaseOrderId = 0;
		PurchaseOrderDTO purchaseOrderDTO = null;
		PurchaseOrderChargeDTO purchaseOrderChargeDTO = null;
		PurchaseOrderChargeView purchaseOrderChargeView = null;
		PurchaseOrderDAO purchaseOrderDAO = null;
		PurchaseOrderChargeDAO purchaseOrderChargeDAO = null;
		List purchaseOrderCharges = null;
		try{
			if (purchaseOrderView != null){
				purchaseOrderDAO = new PurchaseOrderDAO();
				purchaseOrderDTO = PurchaseOrderConverter.convert(purchaseOrderView);
				if( generatorUsed ){
					purchaseOrderId = purchaseOrderDAO.insertPurchaseOrderGenerator(purchaseOrderDTO);
				}else{
					purchaseOrderId = purchaseOrderDAO.insertPurchaseOrder(purchaseOrderDTO);
				}
				purchaseOrderCharges = purchaseOrderView.getPurchaseOrderCosts();
				if (CollectionUtils.isNotEmpty(purchaseOrderCharges)){
					purchaseOrderChargeDAO = new PurchaseOrderChargeDAO();
					for (Iterator itr = purchaseOrderCharges.iterator(); itr.hasNext(); ){
						purchaseOrderChargeView = (PurchaseOrderChargeView) itr.next();
						purchaseOrderChargeView.setPurchaseOrderId(Integer.toString(purchaseOrderId));
						purchaseOrderChargeDTO = PurchaseOrderChargeConverter.convert(purchaseOrderChargeView);
						purchaseOrderChargeDAO.insertPurchaseOrderCharge(purchaseOrderChargeDTO);
					}
				}
			} else {
				PurchaseProgramException ppe = new PurchaseProgramException(INSERT_PURCHASE_ORDER_ERROR_MESSAGE_KEY, PurchaseProgramException.LAYER_SERVICE, PurchaseProgramException.ACTION_INSERT);
				throw ppe;
			}
			
		} catch(PurchaseProgramException ppe){
			throw ppe;
		} catch(Exception e){
			PurchaseProgramException ppe = new PurchaseProgramException(e, PurchaseProgramException.LAYER_SERVICE, PurchaseProgramException.ACTION_INSERT);
			e.printStackTrace(System.out);
			throw ppe;
		}
	}
	
	public void updatePurchaseOrder(PurchaseOrderView purchaseOrderView) throws PurchaseProgramException{
		PurchaseOrderChargeView purchaseOrderChargeView = null;
		PurchaseOrderDTO purchaseOrderDTO = null;
		PurchaseOrderDAO purchaseOrderDAO = null;
		
		try{
			
			if (purchaseOrderView != null){
				purchaseOrderDAO = new PurchaseOrderDAO();
				purchaseOrderDTO = PurchaseOrderConverter.convert(purchaseOrderView);
				
				purchaseOrderDAO.updatePurchaseOrderById(purchaseOrderDTO);
				
				if (CollectionUtils.isNotEmpty(purchaseOrderView.getPurchaseOrderCosts())){
					
					for (Iterator itr = purchaseOrderView.getPurchaseOrderCosts().iterator(); itr.hasNext(); ){
						purchaseOrderChargeView = (PurchaseOrderChargeView) itr.next();
						
						updatePurchaseOrderChargeAmount(purchaseOrderChargeView);
					}
				}
				
			}
			
		} catch(PurchaseProgramException ppe){
			throw ppe;
		} catch(Exception e){
			PurchaseProgramException ppe = new PurchaseProgramException(e, PurchaseProgramException.LAYER_SERVICE, PurchaseProgramException.ACTION_INSERT);
			
			e.printStackTrace(System.out);
			
			throw ppe;
		}
	}
	
	public void updatePurchaseOrderChargeAmount(PurchaseOrderChargeView purchaseOrderChargeView) throws PurchaseProgramException{
		PurchaseOrderChargeDTO purchaseOrderChargeDTO = null;
		PurchaseOrderChargeDAO purchaseOrderChargeDAO = null;
		
		try{
			
			if (purchaseOrderChargeView != null){
				purchaseOrderChargeDAO = new PurchaseOrderChargeDAO();
				purchaseOrderChargeDTO = PurchaseOrderChargeConverter.convert(purchaseOrderChargeView);
				
				purchaseOrderChargeDAO.updatePurchaseOrderChargeAmountById(purchaseOrderChargeDTO);
			}
			
		} catch(PurchaseProgramException ppe){
			throw ppe;
		} catch(Exception e){
			PurchaseProgramException ppe = new PurchaseProgramException(e, PurchaseProgramException.LAYER_SERVICE, PurchaseProgramException.ACTION_INSERT);
			
			e.printStackTrace(System.out);
			
			throw ppe;
		}
	}
	
	public PurchaseOrderView getPurchaseOrderById(int purchaseOrderId) throws PurchaseProgramException{
		PurchaseOrderView purchaseOrderView = null;
		PurchaseOrderDTO purchaseOrderDTO = null;
		PurchaseOrderDAO purchaseOrderDAO = null;
		List purchaseOrderChargesView = null;
		
		try{
			
			purchaseOrderDTO = new PurchaseOrderDTO();
			purchaseOrderDAO = new PurchaseOrderDAO();
			
			purchaseOrderDTO.setPurchaseOrderId(new Integer(purchaseOrderId));
			
			purchaseOrderDTO = purchaseOrderDAO.getPurchaseOrderById(purchaseOrderDTO);
			
			if (purchaseOrderDTO != null){
				purchaseOrderView = PurchaseOrderConverter.convert(purchaseOrderDTO);	
				purchaseOrderChargesView = getPurchaseOrderChargesByPurchaseOrder(Integer.parseInt(purchaseOrderView.getPurchaseOrderId()));
				
				purchaseOrderView.setPurchaseOrderCosts(purchaseOrderChargesView);
			}
			
		} catch(PurchaseProgramException ppe){
			throw ppe;
		} catch(Exception e){
			PurchaseProgramException ppe = new PurchaseProgramException(e, PurchaseProgramException.LAYER_SERVICE, PurchaseProgramException.ACTION_INSERT);
			
			e.printStackTrace(System.out);
			
			throw ppe;
		}
		
		return purchaseOrderView;
	}
	
	public List getPurchaseOrderChargesByPurchaseOrder(int purchaseOrderId) throws PurchaseProgramException{
		PurchaseOrderChargeDAO purchaseOrderChargeDAO = null;
		List purchaseOrderChargesDTO = null;
		List purchaseOrderChargesView = null;
		
		try{
			
			purchaseOrderChargesView = new ArrayList(0);
			purchaseOrderChargeDAO = new PurchaseOrderChargeDAO();
			
			purchaseOrderChargesDTO = purchaseOrderChargeDAO.getPurchaseOrderChargesByPurchaseOrder(purchaseOrderId);
			
			if (CollectionUtils.isNotEmpty(purchaseOrderChargesDTO)){
				purchaseOrderChargesView = PurchaseOrderChargeConverter.convertDTOList(purchaseOrderChargesDTO);
			}
			
		} catch(PurchaseProgramException ppe){
			throw ppe;
		} catch(Exception e){
			PurchaseProgramException ppe = new PurchaseProgramException(e, PurchaseProgramException.LAYER_SERVICE, PurchaseProgramException.ACTION_SELECT);
			
			e.printStackTrace(System.out);
			
			throw ppe;
		}
		
		return purchaseOrderChargesView;
	}
	
	public List getPurchaseOrdersByTransport(int transportId) throws PurchaseProgramException{
		PurchaseOrderDAO purchaseOrderDAO = null;
		List purchaseOrdersDTO = null;
		List purchaseOrdersView = null;
		
		purchaseOrdersView = new ArrayList(0);
		purchaseOrderDAO = new PurchaseOrderDAO();
		
		try{
			
			purchaseOrdersDTO = purchaseOrderDAO.getPurchaseOrdersByTransportId(new Integer(transportId));
			purchaseOrdersView = PurchaseOrderConverter.convertDTOList(purchaseOrdersDTO);
			
		}  catch(PurchaseProgramException ppe){
			throw ppe;
		} catch(Exception e){
			PurchaseProgramException ppe = new PurchaseProgramException(e, PurchaseProgramException.LAYER_SERVICE, PurchaseProgramException.ACTION_SELECT);
			
			e.printStackTrace(System.out);
			
			throw ppe;
		}
		
		return purchaseOrdersView;
	}
	
	public List getPurchaseOrdersByPlant(int plantId) throws PurchaseProgramException{
		PurchaseOrderDAO purchaseOrderDAO = null;
		List purchaseOrdersDTO = null;
		List purchaseOrdersView = null;
		
		purchaseOrdersView = new ArrayList(0);
		purchaseOrderDAO = new PurchaseOrderDAO();
		
		try{
			
			purchaseOrdersDTO = purchaseOrderDAO.getPurchaseOrdersByPlantId(new Integer(plantId));
			purchaseOrdersView = PurchaseOrderConverter.convertDTOList(purchaseOrdersDTO);
			
		}  catch(PurchaseProgramException ppe){
			throw ppe;
		} catch(Exception e){
			PurchaseProgramException ppe = new PurchaseProgramException(e, PurchaseProgramException.LAYER_SERVICE, PurchaseProgramException.ACTION_SELECT);
			
			e.printStackTrace(System.out);
			
			throw ppe;
		}
		
		return purchaseOrdersView;
	}
	
	public void savePuchaseOrderAssignFuture(PurchaseOrderAssignFuturesView purchaseOrderAssignFuturesView)throws PurchaseProgramException{
		PurchaseOrderAssignFutureView purchaseOrderAssignFutureView = null;
		PurchaseOrderSpotView purchaseOrderSpotView = null;
		PurchaseOrderSpotDTO purchaseOrderSpotDTO = null;
		PurchaseOrderSpotDAO purchaseOrderSpotDAO = null;
		PurchaseOrderSpotConverter purchaseOrderSpotConverter = null;
		PurchaseOrderDAO purchaseOrderDAO = null;
		PurchaseOrderAssignFutureDTO purchaseOrderAssignFutureDTO = null;
		PurchaseOrderConverter purchaseOrderConverter = null;
		List purchaseOrderAssignFutureViews = null;
		List purchaseOrderSpotViews = null;
		Iterator iterator = null;
		boolean assignationExists = false;
		try{
			purchaseOrderConverter = new PurchaseOrderConverter();
			purchaseOrderSpotConverter = new PurchaseOrderSpotConverter();
			purchaseOrderDAO = new PurchaseOrderDAO();
			purchaseOrderSpotDAO = new PurchaseOrderSpotDAO();
			purchaseOrderAssignFutureViews = purchaseOrderAssignFuturesView.getPurchaseOrderAssignFutureViews();
			purchaseOrderSpotViews = purchaseOrderAssignFuturesView.getPurchaseOrderSpotViews();
			iterator = purchaseOrderAssignFutureViews.iterator();
			purchaseOrderDAO.updateBushelPurchaseOrder(purchaseOrderAssignFuturesView.getPurchaseOrderId(),purchaseOrderAssignFuturesView.getBushelPrice());
			purchaseOrderDAO.updateCostCommission(purchaseOrderAssignFuturesView.getPurchaseOrderId(), purchaseOrderAssignFuturesView.getCommission());
			while(iterator.hasNext()){
				purchaseOrderAssignFutureView = (PurchaseOrderAssignFutureView)iterator.next();
				purchaseOrderAssignFutureDTO = purchaseOrderConverter.converterAssignViewToAssignDTO(purchaseOrderAssignFutureView, purchaseOrderAssignFuturesView.getPurchaseOrderId());
				assignationExists = purchaseOrderDAO.existPurchaseOrderAssignFuture(purchaseOrderAssignFutureDTO);
				if( purchaseOrderAssignFutureDTO.getQuantity() > -1 ){
					if( assignationExists ){
						purchaseOrderDAO.updatePurchaseOrderAssignFuture(purchaseOrderAssignFutureDTO);
					}else{
						purchaseOrderDAO.insertPuchaseOrderAssignFuture(purchaseOrderAssignFutureDTO);
					}
				}else{
					purchaseOrderDAO.deletePurchaseOrderAssignFuture(purchaseOrderAssignFutureDTO);
				}
			}
			iterator = purchaseOrderSpotViews.iterator();
			while(iterator.hasNext()){
				purchaseOrderSpotView = (PurchaseOrderSpotView)iterator.next();
				purchaseOrderSpotDTO = purchaseOrderSpotConverter.converterPurchaseOrderSpotViewToDto(purchaseOrderSpotView);
				if( purchaseOrderSpotDTO.getPurchaseOrderSpotId() == 0 ){
					if( purchaseOrderSpotDTO.getPurchaseDate() != null ){
						purchaseOrderSpotDAO.insertPurchaseOrderSpot(purchaseOrderSpotDTO);
					}
				}else{
					if( purchaseOrderSpotDTO.getPurchaseDate() != null ){
						purchaseOrderSpotDAO.updatePurchaseOrderSpot(purchaseOrderSpotDTO);
					}else{
						purchaseOrderSpotDAO.deletePurchaseOrderSpot(purchaseOrderSpotDTO.getPurchaseOrderSpotId());
					}
				}
			}
		}catch (PurchaseProgramException purchaseProgramException) {			
			throw purchaseProgramException;
		}catch (Exception exception){
			PurchaseProgramException purchaseProgramException=null;
			exception.printStackTrace(System.out);
			purchaseProgramException= new PurchaseProgramException(exception , CornPPException.LAYER_SERVICE,CornPPException.ACTION_UPDATE);
			throw purchaseProgramException;
		}
	}
	
	public double getCostCommission(int purchaseOrderId)throws PurchaseProgramException{
		double commission = 0;
		PurchaseOrderDAO purchaseOrderDAO = null;
		try{
			purchaseOrderDAO = new PurchaseOrderDAO();
			commission = purchaseOrderDAO.getCostCommission(purchaseOrderId);
		}  catch(PurchaseProgramException ppe){
			throw ppe;
		} catch(Exception e){
			PurchaseProgramException ppe = new PurchaseProgramException(e, PurchaseProgramException.LAYER_SERVICE, PurchaseProgramException.ACTION_SELECT);
			e.printStackTrace(System.out);
			throw ppe;
		}
		return commission;
	}
}